/**
 *    Copyright 2017-2018 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package com.econage.eccm.test.base.mybatis.mapper.defaultsqlsource;

import com.econage.eccm.test.base.mybatis.adaptation.MybatisConfiguration;
import com.econage.eccm.test.base.mybatis.entity.TableInfo;
import com.econage.eccm.test.base.mybatis.util.CollectionUtils;
import com.econage.eccm.test.base.mybatis.util.SqlUtils;
import com.google.common.collect.Maps;
import org.apache.ibatis.mapping.SqlCommandType;

import java.util.Collection;
import java.util.Map;

public class DefaultSelectMethodSqlSource extends DefaultMethodSqlSource {

    public static final String SELECT_BY_ID = "SELECT %s FROM %s WHERE %s=#{%s}",
                                SELECT_LIST_BY_IDS = "SELECT %s FROM %s WHERE %s IN (%s)",
                                SELECT_PAGE_LIST = "SELECT %s FROM %s";


    private final boolean batch;
    private final boolean page;

    public DefaultSelectMethodSqlSource(
            MybatisConfiguration configuration,
            TableInfo tableInfo,
            boolean batch, boolean page
    ) {
        super(configuration, tableInfo);
        this.batch = batch;
        this.page = page;
    }

    @Override
    protected SqlProviderBinding parseBinding(Object parameterObject) {
        if(page&&batch){
            throw new IllegalStateException("page and batch both true!");
        }
        if(page){
            return parsePageSelect(parameterObject);
        }else if(batch){
            return parseSelectListByIds(parameterObject);
        }else{
            return parseSelect(parameterObject);
        }
    }

    @Override
    public String getMethodId() {
        if(page){
            return "selectListPage";
        }else if(batch){
            return "selectListByIds";
        }else{
            return "selectById";
        }
    }

    @Override
    public SqlCommandType getSqlCommandType() {
        return SqlCommandType.SELECT;
    }

    private SqlProviderBinding parsePageSelect(Object parameterObject){
        //提供基本全局查询逻辑即可，插件会自动侦测主键，并分页排序
        String sql = String.format(
                SELECT_PAGE_LIST,
                tableInfo.getSelectColumns(),
                tableInfo.getTableName()
        );
        return SqlProviderBinding.of(sql);
    }

    private SqlProviderBinding parseSelect(Object parameterObject){
        String sql = String.format(
                SELECT_BY_ID,
                tableInfo.getSelectColumns(),
                tableInfo.getTableName(),
                tableInfo.getKeyColumn(),
                tableInfo.getKeyProperty()
        );
        return SqlProviderBinding.of(sql);
    }


    private SqlProviderBinding parseSelectListByIds(Object parameterObject){
        Collection<?> collectionParam =fetchCollectionTypeParameter(parameterObject);
        if(CollectionUtils.isEmpty(collectionParam)){
            throw new IllegalArgumentException("parameter is empty!");
        }

        Map<String,Object> additionalParameter = Maps.newHashMap();
        String idTokens = SqlUtils.formatCollection2ParameterMappings(
                "","",tableInfo.getKeyProperty(),
                collectionParam,
                additionalParameter
        );
        String sql = String.format(
                SELECT_LIST_BY_IDS,
                tableInfo.getSelectColumns(),
                tableInfo.getTableName(),
                tableInfo.getKeyColumn(),
                idTokens
        );
        return SqlProviderBinding.of(sql,additionalParameter);
    }



}
